﻿using System;
using System.Collections.Generic;
using Shinkansen.Core;
using Shinkansen.Runtime;

namespace Shinkansen.Model
{
    public class ResourceInformation
    {
        private readonly EncryptedQueryString _tokens;


        /// <summary>
        /// Initializes a new instance of the <see cref="ResourceInformation"/> class.
        /// </summary>
        /// <param name="queryString">The query string.</param>
        public ResourceInformation (string queryString)
        {
            QueryString qs = new QueryString (queryString);
            string encryptedToken = qs[Tokens.SecureToken];

            if (string.IsNullOrEmpty (encryptedToken))
                throw new InvalidOperationException ("Missing encrypted token of the resource.");

            _tokens = new EncryptedQueryString (encryptedToken);
        }

        /// <summary>
        /// Gets the original token.
        /// </summary>
        /// <value>The original token.</value>
        public string OriginalToken
        {
            get { return _tokens.ToString (); }
        }

        /// <summary>
        /// Gets or sets a value indicating whether to crunch this resource.
        /// </summary>
        /// <value><c>true</c> if crunch; otherwise, <c>false</c>.</value>
        public bool Crunch
        {
            get { return _tokens.ContainsKey (Tokens.Crunch) && Convert.ToBoolean (_tokens[Tokens.Crunch]); }
        }

        /// <summary>
        /// Gets the paths.
        /// </summary>
        /// <value>The paths.</value>
        public IEnumerable<string> Paths
        {
            get { return _tokens[Tokens.Path].Split ('|'); }
        }

        /// <summary>
        /// Gets a value indicating whether this <see cref="ResourceInformation"/> is compress.
        /// </summary>
        /// <value><c>true</c> if compress; otherwise, <c>false</c>.</value>
        public bool Compress
        {
            get { return CompressionMode != HttpCompressionMode.None; } 
        }

        /// <summary>
        /// Gets the compression mode.
        /// </summary>
        /// <returns></returns>
        public HttpCompressionMode CompressionMode
        {
            get
            {
                if (!_tokens.ContainsKey (Tokens.Compression)) 
                    return HttpCompressionMode.None;

                HttpCompressionMode mode;
                string compressionToken = _tokens[Tokens.Compression];

                switch (compressionToken)
                {
                    case Tokens.GzipCompression:        mode = HttpCompressionMode.GZip; break;
                    case Tokens.DeflateCompression:     mode = HttpCompressionMode.Deflate; break;

                    default:
                        throw new InvalidOperationException (string.Format ("Unrecognized HTTP compression mode '{0}'.", compressionToken));
                }

                return mode;
            }
        }

        /// <summary>
        /// Gets the type of the resource.
        /// </summary>
        /// <value>The type of the resource.</value>
        public ResourceType ResourceType
        {
            get 
            {
                ResourceType type;
                string typeToken = _tokens[Tokens.FileType];

                switch (typeToken)
                {
                    case Tokens.JavaScript:     type = ResourceType.JavaScript; break;
                    case Tokens.Css:            type = ResourceType.Css; break;
                    case Tokens.Image:          type = ResourceType.Image; break;

                    default:
                        throw new InvalidOperationException (string.Format ("Unrecognized resource type '{0}'.", typeToken));
                }

                return type;
            }
        }
    }
}